package com.zijidelu.luframework.utils.persistence.mybatisplus;

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * MybatisPlus常量池。
 *
 * @author ZIJIDELU
 * @date: 2023/12/29 14:23
 */
public interface MybatisPlusConstant {
    /**
     * AbstractChainWrapper类中QueryWrapper字段名
     */
    String WRAPPER_CHILDREN_FIELD_NAME = "wrapperChildren";

    /**
     * 构建Wrapper必须字段entity
     */
    String ENTITY_FIELD_NAME = "entity";

    /**
     * 构建Wrapper必须字段entityClass
     */
    String ENTITY_CLASS_FIELD_NAME = "parentEntityClass";

    /**
     * 构建Wrapper必须字段sqlSelect
     */
    String SQL_SELECT_FIELD_NAME = "sqlSelect";

    /**
     * 构建Wrapper必须字段paramNameSeq
     */
    String PARAM_NAME_SEQ_FIELD_NAME = "paramNameSeq";

    /**
     * 构建Wrapper必须字段paramNameValuePairs
     */
    String PARAM_NAME_VALUE_PAIRS_FIELD_NAME = "paramNameValuePairs";

    /**
     * 构建Wrapper必须字段expression
     */
    String EXPRESSION_FIELD_NAME = "expression";

    /**
     * 构建Wrapper必须字段paramAlias
     */
    String PARAM_ALIAS_FIELD_NAME = "paramAlias";

    /**
     * 构建Wrapper必须字段lastSql
     */
    String LAST_SQL_FIELD_NAME = "lastSql";

    /**
     * 构建Wrapper必须字段sqlComment
     */
    String SQL_COMMENT_FIELD_NAME = "sqlComment";

    /**
     * 构建Wrapper必须字段sqlFirst
     */
    String SQL_FIRST_FIELD_NAME = "sqlFirst";

    /**
     * Mybatis Plus wrapper转换所需内部字段
     */
    Set<String> BUILD_QUERY_WRAPPER_REQUIRED_FIELD_NAMES = Collections.unmodifiableSet(Stream.of(
            MybatisPlusConstant.ENTITY_FIELD_NAME,
            MybatisPlusConstant.ENTITY_CLASS_FIELD_NAME,
            MybatisPlusConstant.SQL_SELECT_FIELD_NAME,
            MybatisPlusConstant.PARAM_NAME_SEQ_FIELD_NAME,
            MybatisPlusConstant.PARAM_NAME_VALUE_PAIRS_FIELD_NAME,
            MybatisPlusConstant.EXPRESSION_FIELD_NAME,
            MybatisPlusConstant.PARAM_ALIAS_FIELD_NAME,
            MybatisPlusConstant.LAST_SQL_FIELD_NAME,
            MybatisPlusConstant.SQL_COMMENT_FIELD_NAME,
            MybatisPlusConstant.SQL_FIRST_FIELD_NAME
    ).collect(Collectors.toSet()));

    /**
     * QueryWrapper所有Method
     */
    List<Field> QUERY_WRAPPER_FIELDS = Collections.unmodifiableList(Arrays.stream(ReflectUtil.getFields(QueryWrapper.class)).collect(Collectors.toList()));

    /**
     * QueryWrapper所有Method名称Map
     */
    Map<String, Field> QUERY_WRAPPER_FIELD_MAP = Collections.unmodifiableMap(QUERY_WRAPPER_FIELDS.stream().collect(Collectors.toMap(Field::getName, field -> field)));

    /**
     * LambdaQueryWrapper所有Method
     */
    List<Field> LAMBDA_QUERY_WRAPPER_FIELDS = Collections.unmodifiableList(Arrays.stream(ReflectUtil.getFields(LambdaQueryWrapper.class)).collect(Collectors.toList()));

    /**
     * LambdaQueryWrapper所有Method名称Map
     */
    Map<String, Field> LAMBDA_QUERY_WRAPPER_FIELD_MAP = Collections.unmodifiableMap(LAMBDA_QUERY_WRAPPER_FIELDS.stream().collect(Collectors.toMap(Field::getName, field -> field)));

    /**
     * QueryChainWrapper所有Method
     */
    List<Field> QUERY_CHAIN_WRAPPER_FIELDS = Collections.unmodifiableList(Arrays.stream(ReflectUtil.getFields(QueryChainWrapper.class)).collect(Collectors.toList()));

    /**
     * QueryChainWrapper所有Method名称Map
     */
    Map<String, Field> QUERY_CHAIN_WRAPPER_FIELD_MAP = Collections.unmodifiableMap(QUERY_CHAIN_WRAPPER_FIELDS.stream().collect(Collectors.toMap(Field::getName, field -> field)));

    /**
     * LambdaQueryChainWrapper所有Method
     */
    List<Field> LAMBDA_QUERY_CHAIN_WRAPPER_FIELDS = Collections.unmodifiableList(Arrays.stream(ReflectUtil.getFields(LambdaQueryChainWrapper.class)).collect(Collectors.toList()));

    /**
     * LambdaQueryChainWrapper所有Method名称Map
     */
    Map<String, Field> LAMBDA_QUERY_CHAIN_WRAPPER_FIELD_MAP = Collections.unmodifiableMap(QUERY_CHAIN_WRAPPER_FIELDS.stream().collect(Collectors.toMap(Field::getName, field -> field)));

}
